﻿using System;
using System.Web.Mvc;
using FBGraph.Web.Security;

namespace FBGraph.Web.Mvc
{
    /// <summary>Provides basic functionality for authorization services based on Facebook's Graph API authentication.</summary>
    public class FBGraphAuthenticationController : FBGraphMvcController
    {
        /// <summary>Redirects the user to Facebook's Graph API authorization page.</summary>
        /// <param name="returnUrl">The url the user will be redirected to after successful authorization. If a null reference is specified, the user will be redirected
        /// back to the page they originally came from.</param>
        /// <param name="scope">A mapping of <see cref="ExtendedPermission" />s that will be requested.</param>
        public ActionResult Authorize(String returnUrl, ExtendedPermission? scope)
        {
            var authControllerName = this.GetType().Name.Replace("Controller", String.Empty).ToLowerInvariant();
            var postAuthorizeUrl = String.Format("{0}/postauthorize", authControllerName);

            var redirectUrl = this.FbContext.PrepareAuthUrl(postAuthorizeUrl, returnUrl, scope, false);

            return Redirect(redirectUrl);
        }

        /// <summary>Handles the callback from Facebook's OAuth provider.</summary>
        /// <param name="code">The authorization code returned by Facebook's OAuth provider, which is used to request an access token.</param>
        /// <param name="id">A <see cref="Guid" /> identifier generated by the FBGraph.NET client to identify a specific authorization request.</param>
        public ActionResult PostAuthorize(String code, Guid id)
        {
            AuthRequestData requestData;
            if (this.FbContext.ProcessAuthenticationCallback(code, id, out requestData)) return Redirect(requestData.ReturnUrl);
            else return RedirectToAction("Authorize", new { returnUrl = requestData.ReturnUrl, scope = requestData.Scope });
        }

        /// <summary>Removes all user-specific cookies, effectively logging the user out of the application.</summary>
        /// <param name="returnUrl">The url the user will be redirected to after removing the cookies. If a null reference is specified, the user will be 
        /// redirected to the root of the application.</param>
        /// <remarks>
        /// Note: This does not revoke the user's authorization of an application, nor does it revoke any extended permissions.
        /// </remarks>
        public ActionResult LogOut(String returnUrl)
        {
            this.FbContext.RemoveAccessToken();
            this.FbContext.RemoveApplicationUserCookie();
            this.FbContext.RemoveExtendedPermissions();

            return Redirect(returnUrl ?? "~/");
        }
    }
}